package com.energyfuture.auth.service;

import com.alibaba.nacos.shaded.com.google.protobuf.ServiceException;
import com.energyfuture.auth.form.RegisterBody;
import com.energyfuture.auth.utils.IpUtil;
import com.energyfuture.common.core.utils.ServletUtils;
import com.energyfuture.common.core.utils.ip.IpUtils;
import com.energyfuture.common.security.service.TokenService;
import com.energyfuture.system.api.domain.SysCompany;
import com.energyfuture.system.api.domain.SysLogininfor;
import com.energyfuture.system.api.model.SegmentEntity;
import com.energyfuture.system.api.model.SysparaEntity;
import com.energyfuture.auth.utils.RSAUtil;
import org.apache.commons.collections4.bag.HashBag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.stereotype.Component;
import com.energyfuture.common.core.constant.Constants;
import com.energyfuture.common.core.constant.UserConstants;
import com.energyfuture.common.core.domain.R;
import com.energyfuture.common.core.enums.UserStatus;
import com.energyfuture.common.core.exception.BaseException;
import com.energyfuture.common.core.utils.SecurityUtils;
import com.energyfuture.common.core.utils.StringUtils;
import com.energyfuture.system.api.RemoteLogService;
import com.energyfuture.system.api.RemoteUserService;
import com.energyfuture.system.api.domain.SysUser;
import com.energyfuture.system.api.model.LoginUser;
import sun.security.util.SecurityConstants;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import java.math.BigInteger;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 登录校验方法
 *
 * @author energyfuture
 */
@Component
public class SysLoginService {
    @Autowired
    private RemoteLogService remoteLogService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private TokenService tokenService;

    /**
     * 登录
     */
    public LoginUser login(String username, String password, HttpServletRequest request) {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        //密码解密
        try {
            byte[] en_result = new BigInteger(password, 16).toByteArray();
            byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(), en_result);
            StringBuffer sb = new StringBuffer();
            sb.append(new String(de_result));
            String spass = sb.reverse().toString();
            System.out.println(spass);
            password = URLDecoder.decode(spass, "UTF-8");//
        } catch (Exception e) {
        	e.printStackTrace();
            throw new BaseException("非法登录请求");
        }

        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
            throw new BaseException("用户/密码必须填写");
        }
        // 密码如果不在指定范围内 错误
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
            throw new BaseException("用户密码不在指定范围");
        }
        // 用户名不在指定范围内 错误
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
            throw new BaseException("用户名不在指定范围");
        }
        // 查询用户信息
        R<LoginUser> userResult = remoteUserService.getUserInfo(username);

        //查询系统参数
        R<SysparaEntity> sysparaResult = remoteUserService.querySysParam();
        SysparaEntity sysparaEntity = sysparaResult.getData();

        if (R.FAIL == userResult.getCode()) {
            throw new BaseException(userResult.getMsg());
        }

        if (StringUtils.isNull(userResult.getData())) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
            throw new BaseException("登录用户：" + username + " 不存在");
        }
        LoginUser userInfo = userResult.getData();
        SysUser user = userResult.getData().getSysUser();
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "对不起，您的账号已被删除");

            throw new BaseException("对不起，您的账号：" + username + " 已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户已停用，请联系管理员");
            throw new BaseException("对不起，您的账号：" + username + " 已停用");
        }

        /********************用户信息验证开始***************************/
        //1.检查临时账号是否休眠/锁定/注销
        if (user.getLocked() != null && "1".equals(user.getLocked())) {
            if (validateUserLocked(user.getLockedTime(), Integer.parseInt(sysparaEntity.getDlsdsj()))) {
                user.setLocked("0");
                remoteUserService.updateUser(user);
            } else {
                remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户已锁定，请联系管理员");
                throw new BaseException("对不起，您的账号：" + username + " 已锁定");
            }

        }

        /********************用户信息验证结束***************************/

        Integer lockedCount = user.getLockedCount() == null ? 0 : user.getLockedCount();
        if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户密码错误");
            if (lockedCount == null) {
                user.setLockedCount(0);
                remoteUserService.updateUser(user);
            } else {
                int dlsbcs = Integer.parseInt((sysparaEntity.getDlsbcs() == null) ? "5" : sysparaEntity.getDlsbcs());
                // 尝试登录次数+1
                user.setLockedCount(++lockedCount);
                if (lockedCount >= dlsbcs) {
                    user.setLocked("1");
                    user.setLockedCount(0);
                    remoteUserService.updateUser(user);
                    remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户已锁定，请联系管理员");
                    remoteUserService.updateUser(user);
                    throw new BaseException("对不起，您的账号：" + username + " 已锁定,请" + sysparaEntity.getDlsdsj() + "分钟后重试！");
                } else {
                    throw new BaseException("用户名或密码不正确,还有" + (dlsbcs - lockedCount) + "次机会!");
                }
            }

            throw new BaseException("用户不存在/密码错误");
        } else if (lockedCount != 0) {
            user.setLockedCount(0);
            remoteUserService.updateUser(user);
        }





        remoteLogService.saveLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
        return userInfo;
    }

    public void logout(String loginName) {
        remoteLogService.saveLogininfor(loginName, Constants.LOGOUT, "退出成功");
    }

    /**
     * 比较两个时分字符串大小
     *
     * @param s1
     * @param s2
     * @return
     */
    public boolean compTime(String s1, String s2) {
        try {
            if (s1.indexOf(":") < 0 || s1.indexOf(":") < 0) {
                return false;
            } else {
                String[] array1 = s1.split(":");
                int total1 = Integer.valueOf(array1[0]) * 3600 + Integer.valueOf(array1[1]) * 60;
                String[] array2 = s2.split(":");
                int total2 = Integer.valueOf(array2[0]) * 3600 + Integer.valueOf(array2[1]) * 60;
                return total1 - total2 >= 0 ? true : false;
            }
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            return false;
        }
    }

    /**
     * 检查ip是否在范围内登陆
     *
     * @param ip
     * @param userEntity
     * @return
     */
    public String checkIp(String ip, SysUser userEntity) {
        R<List<SegmentEntity>> ipsResult = remoteUserService.selectSysIPs();
        List<SegmentEntity> segmentEntitys = ipsResult.getData();
        String result = null;
        if (segmentEntitys != null && segmentEntitys.size() > 0) {
            for (int j = 0; j < segmentEntitys.size(); j++) {
                SegmentEntity segmentEntity = segmentEntitys.get(j);
                //1代表关闭IP限制
                if(segmentEntity.getIpState()!=null && !"1".equals(segmentEntity.getIpState())) {
                	//检查当前ip是否符合系统的ip限制
                    if (org.apache.commons.lang3.StringUtils.isNotEmpty(segmentEntity.getIpStart()) && org.apache.commons.lang3.StringUtils.isNotEmpty(segmentEntity.getIpEnd())) {
                        String[] nowIp = ip.split("\\.");
                        String[] startIp = segmentEntity.getIpStart().split("\\.");
                        String[] endIp = segmentEntity.getIpEnd().split("\\.");
                        for (int i = 0; i < nowIp.length; i++) {
                            if (Integer.parseInt(nowIp[i]) > Integer.parseInt(startIp[i])
                                    && Integer.parseInt(nowIp[i]) < Integer.parseInt(endIp[i])) {
                                result = null;
                            } else if (Integer.parseInt(nowIp[i]) == Integer.parseInt(startIp[i])
                                    || Integer.parseInt(nowIp[i]) == Integer.parseInt(endIp[i])) {
                            } else {
                                result = "您登录的IP不在有效范围内。";
                            }
                        }
                    }
                }
            }
            if (result != null) {
                return result;
            }
            //ip检查,针对单一用户的ip,在user表里配置
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(userEntity.getIpStart()) && org.apache.commons.lang3.StringUtils.isNotEmpty(userEntity.getIpEnd())) {
                String[] nowIp = ip.split("\\.");
                String[] startIp = userEntity.getIpStart().split("\\.");
                String[] endIp = userEntity.getIpEnd().split("\\.");
                for (int i = 0; i < nowIp.length; i++) {
                    if (Integer.parseInt(nowIp[i]) > Integer.parseInt(startIp[i])
                            && Integer.parseInt(nowIp[i]) < Integer.parseInt(endIp[i])) {
                        return null;
                    } else if (Integer.parseInt(nowIp[i]) == Integer.parseInt(startIp[i])
                            || Integer.parseInt(nowIp[i]) == Integer.parseInt(endIp[i])) {
                    } else {
                        return "您登录的IP不在有效范围内。";
                    }
                }
            }
        } else {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(userEntity.getIpStart()) && org.apache.commons.lang3.StringUtils.isNotEmpty(userEntity.getIpEnd())) {
                String[] nowIp = ip.split("\\.");
                String[] startIp = userEntity.getIpStart().split("\\.");
                String[] endIp = userEntity.getIpEnd().split("\\.");
                for (int i = 0; i < nowIp.length; i++) {
                    if (Integer.parseInt(nowIp[i]) > Integer.parseInt(startIp[i])
                            && Integer.parseInt(nowIp[i]) < Integer.parseInt(endIp[i])) {
                        return null;
                    } else if (Integer.parseInt(nowIp[i]) == Integer.parseInt(startIp[i])
                            || Integer.parseInt(nowIp[i]) == Integer.parseInt(endIp[i])) {
                    } else {
                        return "您登录的IP不在有效范围内。";
                    }
                }
            }
        }
        //logService.log(log);
        return result;
    }

    public boolean validateUserLocked(Date lockedTime, int lockedMin) {
        long lt = lockedTime.getTime();
        long now = new Date().getTime();
        long finalLockedTime = lt + (lockedMin * 60 * 1000);
        //如果锁定的日期加上参数表的登陆锁定时间大于当前时间，则表示还在锁定状态
        if (finalLockedTime > now) {
            return false;
        }
        return true;
    }

    /**
     * 检查密码修改的日期是否超过参数表设置的日期
     *
     * @param pwdUpdateTime
     * @param expday
     * @return
     */
    public boolean validatePasswordExpdate(Date pwdUpdateTime, int expday) {
        long updtTime = pwdUpdateTime.getTime();
        long nowTime = new Date().getTime();
        double time = (nowTime - updtTime) / 1000.0 / 3600.0 / 24.0;
        if (time > expday) {
            return false;
        }
        return true;
    }

    //添加
    /**
     * 注册
     */
    public void register(RegisterBody registerBody)
    {
        // 获取企业信息
        R<SysCompany> companyInfo = remoteUserService.getCompanyInfo(registerBody.getCompanyID());
        // 企业邀请码不正确
        if(registerBody.getCompanyID() != (companyInfo.getData().getId()))
        {
            throw new BaseException("企业邀请码不正确");
        }

        String username = registerBody.getUserName();
        String password = registerBody.getPassWord();
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password))
        {
            throw new BaseException("用户/密码必须填写");
        }
        // 用户名不在指定范围内 错误
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
        {
            throw new BaseException("账户长度必须在2到20个字符之间");
        }
        // 密码不在指定范围内 错误
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
        {
            throw new BaseException("密码长度必须在5到20个字符之间");
        }
        // 确认密码不正确
        if (password != registerBody.getPassWord1() )
        {
            throw new BaseException("两次输入的密码不一致");
        }

        // 注册用户信息
        SysUser sysUser = new SysUser();
        sysUser.setCompanyId(registerBody.getCompanyID());
        sysUser.setUserName(username);
        sysUser.setNickName(username);
        sysUser.setDeptName(registerBody.getDeptName());
        sysUser.setUserPost(registerBody.getUserPost());
        sysUser.setPassword(SecurityUtils.encryptPassword(password));
        R<?> registerResult = remoteUserService.registerUserInfo(sysUser);

        if (R.FAIL == registerResult.getCode())
        {
            throw new BaseException(registerResult.getMsg());
        }
        remoteLogService.saveLogininfor(username, Constants.REGISTER_SUCCESS, "注册成功");
    }


}
